package com.aabte.springbootopenfeigndemo.core.exception;

import com.aabte.springbootopenfeigndemo.core.bean.Response;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandle {

    @Resource
    private ObjectMapper objectMapper;

    @ExceptionHandler({ApplicationValidationException.class, ApplicationDomainException.class})
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public void handleBadRequestException(HttpServletRequest request, HttpServletResponse response, ApplicationException e) throws IOException {
        logWarn(e);
        Response<?> result = Response.builder().code(e.getCode()).msg(e.getMessageWithoutCode()).build();
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(objectMapper.writeValueAsBytes(result));
    }

    @ExceptionHandler(ApplicationException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public void handleApplicationException(HttpServletRequest request, HttpServletResponse response, ApplicationException e) throws IOException {
        logError(e);
        Response<?> result = Response.builder().code(e.getCode()).msg(e.getMessageWithoutCode()).build();
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(objectMapper.writeValueAsBytes(result));
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public void handleException(HttpServletRequest request, HttpServletResponse response, Exception e) throws IOException {
        logError(e);
        Response<?> result = Response.builder().code("sys.error").msg("").build();
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(objectMapper.writeValueAsBytes(result));
    }

    private void logError(Exception e) {
        log.error("", e);
    }

    private void logWarn(Exception e) {
        log.warn("", e);
    }

}
